#include <my_header.h>

// 全局变量，用于统计总目录数
static int dirs = 0;
static int files =0;

// 深度优先搜索打印目录树
// dirpath:要递归遍历的根目录
// width: 打印宽度，用于控制缩进，增强视觉层次感
void DFS_print(char *dirpath, int width)
{
    DIR *dirp = opendir(dirpath);
    ERROR_CHECK(dirp, NULL, "opendir");  // 检查目录是否成功打开

    struct dirent *pdirent;
    // 循环读取目录项
    while((pdirent = readdir(dirp)) != NULL)
    {
        // 跳过"."和".."这两个特殊目录
        if(strcmp(pdirent->d_name, ".") == 0 ||
            strcmp(pdirent->d_name, "..") == 0)
        {
            continue;
        }

        // 打印前缀和缩进，构建树形结构的视觉效果
        printf("└");
        for(int i=1; i<width; i++)
        {
            printf("─");
        }

        // 打印当前文件或目录的名称
        printf("%s\n", pdirent->d_name);
        // 如果是目录，递归调用自己，继续深度遍历
        // man 3 readdir查看DT_DIR
        if(pdirent->d_type == DT_DIR)
        {
            // DT_DIR表示目录文件
            dirs++;
            // 2. chdir切换目录 递归调用 不建议
            int ret = chdir(pdirent->d_name);   // 改变工作目录到当前遍历的目录
            ERROR_CHECK(ret, -1, "chdir");  // 检查目录是否成功切换
            // 工作目录切换成功后，递归的对当前目录进行深入遍历
            DFS_print(".", width + 4);  
            ret = chdir("..");  // 当前目录已遍历完毕，返回上一级目录
            ERROR_CHECK(ret, -1, "chdir");    // 检查是否成功返回
        }
        else{
            files++;    // 文件数++
        }
    }
    // 遍历完成，关闭目录
    closedir(dirp);
}


/* Usage: ./my_tree pathname*/
int main(int argc, char *argv[]){                                  
    ARGS_CHECK(argc, 2);
    // 打印根目录名称
    printf("%s\n", argv[1]);
    // 从根目录开始深度优先遍历打印目录树，初始打印4个
    int ret = chdir(argv[1]);   // 改变提供的根目录
    ERROR_CHECK(ret, -1, "chdir");
    DFS_print(".", 4);  // 从根目录开始深度优先比那里打印目录树
                        // 初始打印4个横杠
    printf("\n %d directories, %d files\n", dirs, files);
    return 0;
}


